package com.lemontree.web.controller.System;

import com.lemontree.common.baseEnum.ResCode;
import com.lemontree.common.utils.AjaxResult;
import com.lemontree.common.utils.CodeUtil;
import com.lemontree.common.utils.SHA256Util;
import com.lemontree.common.utils.StringUtil;
import com.lemontree.common.utils.email.EmailUtils;
import com.lemontree.common.utils.redis.RedisManager;
import com.lemontree.core.shiro.token.TokenManager;
import com.lemontree.web.controller.BaseController;
import com.lemontree.web.entity.User;
import com.lemontree.web.model.UserModel;
import com.lemontree.web.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * Created by lemontree on 2016/8/23.
 */
@Controller("LoginController")
@RequestMapping("/user")
public class LoginController extends BaseController {

    @Autowired
    private UserService userService;

    /**
     * 登录页跳转
     * @param request 请求头
     * @param response 响应头
     * @return
     */
    @RequestMapping(value = "/login.htm", method = RequestMethod.GET)
    public String login(HttpServletRequest request, HttpServletResponse response) {
        return "login";
    }

    /**
     * 登录页跳转
     * @param request 请求头
     * @param response 响应头
     * @return
     */
    @RequestMapping(value = "/register.htm", method = RequestMethod.GET)
    public String reg(HttpServletRequest request, HttpServletResponse response) {
        return "reg";
    }


    /**
     *  登录
     * @param user 登录信息 用户名/密码
     * @param Remember 是否记住
     * @param request 请求头
     * @return 返回跳转地址
     */
    @RequestMapping(value = "/login.htm", method = RequestMethod.POST)
    public @ResponseBody HashMap<String,Object> login(User user, boolean Remember, HttpServletRequest request) {
        // UserModel checkUser = checkPwd(user);
        // if (null == checkUser) {
        // result.setRes(ResCode.LOGIN_ERROR);
        // } else {
        // request.getSession().setAttribute("user", checkUser);
        // }
        HashMap<String,Object> map = new LinkedHashMap<String, Object>();
        try {
            user.setPassword(SHA256Util.getSHA256Str(user.getPassword()));
            TokenManager.login(user, Remember);
            map.put(RES_CODE,ResCode.OK.getRetCode());
            map.put(RES_MSG, ResCode.OK.getDesc());

            // shiro获取登录前的url地址
            SavedRequest savedRequest = WebUtils.getSavedRequest(request);
            String url = "";
            // 获取登录之前的url
            if (null != savedRequest) {
                url = savedRequest.getRequestUrl();
            }
            LOG.info(String.format("登录前的url为：%s", url));
            if (StringUtil.isBlank(url)) {
                url = request.getContextPath() + "/index.htm";
            }
            map.put("back_url",url);
        } catch (DisabledAccountException e) {
            map.put(RES_CODE,ResCode.LOGIN_FAIL.getRetCode());
            map.put(RES_MSG, e.getMessage());
            return map;
        } catch (AccountException e){
            map.put(RES_CODE,ResCode.LOGIN_FAIL.getRetCode());
            map.put(RES_MSG, e.getMessage());
            return map;
        }catch (Exception e) {
            LOG.error("/login.htm -> POST ->"+e.getMessage());
            map.put(RES_CODE,ResCode.SERVICE_ERROR.getRetCode());
            map.put(RES_MSG, ResCode.SERVICE_ERROR.getDesc());
            return map;
        }
        return map;
    }

    @RequestMapping(value = "/logout.htm", method = RequestMethod.POST)
    public @ResponseBody AjaxResult loginOut() {
        AjaxResult result = new AjaxResult(ResCode.OK);
        try {
            TokenManager.logout();
        }catch (Exception e){
            result.setRes(ResCode.SERVICE_ERROR);
        }
        return result;
    }

    /**
     * 监测用户名密码是否正确
     * @param user 前端获取的登录信息
     * @return false：用户名密码错误；true：登录通过
     */
    private UserModel checkPwd(User user) {
        if (null == user) {
            return null;
        }
        User dbUser = userService.getUserByUserName(user.getUserName());
        if (null == dbUser) {
            return null;
        }
        user.setPassword(SHA256Util.getSHA256Str(user.getPassword()));
        if (!dbUser.getPassword().equals(user.getPassword())) {
            return null;
        }
        UserModel userModel = new UserModel();
        userModel.setUserName(dbUser.getUserName());
        return userModel;
    }

    /**
     * 用户注册
     * @param user 用户信息
     * @return 成功信息
     */
    @RequestMapping(value = "/regUser.htm", method = RequestMethod.POST)
    public @ResponseBody AjaxResult regUser(User user, @RequestParam("emailCode") String emailCode,
            HttpServletRequest request) {
        AjaxResult result = new AjaxResult(ResCode.OK);
        try {
            // 用户填写校验校验
            if (!User.userValidator(user, result)) {
                result.setRes(ResCode.INVALID_ARG);
                return result;
            }
            // 获取邮箱验证码
            String redisEmailCode = RedisManager
                    .getString(EmailUtils.EMIAL_CODE_EXIST + user.getEmail());
            // 邮箱验证码是否失效
            if (StringUtil.isBlank(redisEmailCode)) {
                result.setRes(ResCode.INVALID_EMAIL_CODE);
                return result;
            }
            // 邮箱验证码是否一致
            if (!redisEmailCode.equals(emailCode)) {
                result.setRes(ResCode.ERROR_EMAIL_CODE);
                return result;
            }
            // 获取数据库相关用户信息，存在则提示登录
            // 验证手机号是否已经注册
            List<User> dbUserByPhone = userService.getUserByPhone(user.getPhone());
            if (CollectionUtils.isNotEmpty(dbUserByPhone)) {
                result.setRes(ResCode.REG_PHONE_EXIST);
                return result;
            }
            // 判断用户名是否已被注册
            User dbUserByName = userService.getUserByUserName(user.getUserName());
            if (null != dbUserByName) {
                result.setRes(ResCode.REG_PHONE_EXIST);
                return result;
            }
            // 密码加密SHA-256
            user.setSecurityKey(SHA256Util.getSecurtityKey());
            user.setPassword(SHA256Util.getSHA256Str(user.getPassword() + user.getSecurityKey()));
            userService.insertUsers(user);
            // TODO 后期转的实体类开发
            UserModel userModel = new UserModel();
            userModel.setUserName(user.getUserName());
            userModel.setUserPhotoUrl(user.getUserPhotoUrl());
            userModel.setEmail(user.getEmail());
            request.getSession().setAttribute("user", userModel);
        } catch (Exception e) {
            LOG.error("user/regUser.htm : " + e.getMessage());
            return AjaxResult.failuer(ResCode.SERVICE_ERROR.getRetCode(),
                    ResCode.SERVICE_ERROR.getDesc());
        }
        return result;
    }

    /**
     * 发送邮箱验证码
     * @param receiveEmail 接受邮箱
     * @return 确认信息
     */
    @RequestMapping(value = "regUser.htm", method = RequestMethod.POST,
            params = "action=getEmailCode")
    public @ResponseBody AjaxResult getEmailCode(@RequestParam("email") String receiveEmail) {
        AjaxResult result = new AjaxResult(ResCode.EMAIL_SEND_SUCCESS);
        try {
            if (!EmailUtils.validatEmail(receiveEmail)) {
                result.setRes(ResCode.ERROR_EMAIL);
                return result;
            }
            // 先验证邮箱，后验证用户名的信息减少数据库操作
            if (!EmailUtils.validateEmialCode(receiveEmail)) {
                result.setRes(ResCode.EMAIL_CODE_TIME_IN);
                return result;
            }
            // 判断是5分钟内发送的，清空原来的验证码
            if (StringUtil.isNotBlank(
                    RedisManager.getString(EmailUtils.EMIAL_CODE_EXIST + receiveEmail))) {
                RedisManager.delByKey(receiveEmail);
            }
            // 产生随机的邮箱验证码
            String emailCode = CodeUtil.getCode(4);
            // 先发生邮箱，后塞redis
            EmailUtils.sendEmail(receiveEmail, emailCode);
            // redis 中塞值，有效时间是60秒
            RedisManager.setStringExpire(EmailUtils.EMAIL_CODE_KEY + receiveEmail, emailCode,
                    EmailUtils.REDIS_EMAIL_SECONDS);
            // redis 中塞值，有效时间是5分钟
            RedisManager.setStringExpire(EmailUtils.EMIAL_CODE_EXIST + receiveEmail, emailCode,
                    EmailUtils.REDIS_EMAIL_MINUTES);
        } catch (Exception e) {
            LOG.error(".................action=sendEmail error: " + e.toString());
            result.setRes(ResCode.FAIL);
        }
        return result;
    }

}
